From e6b8ec725f580bef91483c77fab63a333afcf78f Mon Sep 17 00:00:00 2001 From: tsteven4 <13596209+tsteven4@users.noreply.github.com> Date: Wed, 20 Nov 2019 10:57:48 -0700 Subject: [PATCH] fix format vector consistency issues (#422) * fix format vector consistency issues. * fix leaks in sort_and_unify_vecs. * fix vec init for msvc2015. * Revert "fix vec init for msvc2015." This reverts commit 02b85801ee4d1de24101713fbd85c33238da6183. * Revert "fix leaks in sort_and_unify_vecs." This reverts commit d634c21f9f7767d198750e61ba426eb7850127a9. * only validate formats for real types. --- defs.h | 1 + globalsat_sport.cc | 75 ++++++++--------------------- itracku.cc | 33 +++++++++---- main.cc | 8 +++- navicache.cc | 22 ++------- pocketfms_fp.cc | 8 +--- saroute.cc | 8 +--- testo.d/validate_formats.test | 2 + tpo.cc | 41 +++++++++++----- vecs.cc | 88 +++++++++++++++++++++++++++++++++++ vpl.cc | 8 +--- yahoo.cc | 10 +--- 12 files changed, 178 insertions(+), 126 deletions(-) create mode 100644 testo.d/validate_formats.test diff --git a/defs.h b/defs.h index ebfc32a3e..67ac6a90e 100644 --- a/defs.h +++ b/defs.h @@ -1071,6 +1071,7 @@ void assign_option(const char* vecname, arglist_t* ap, const char* val); void disp_vec_options(const char* vecname, arglist_t* ap); void disp_vecs(); void disp_vec(const char* vecname); +int validate_formats(); void init_vecs(); void exit_vecs(); void disp_formats(int version); diff --git a/globalsat_sport.cc b/globalsat_sport.cc index 0a0063e5a..eb69f07f6 100644 --- a/globalsat_sport.cc +++ b/globalsat_sport.cc @@ -48,9 +48,9 @@ static void* serial_handle; static bool isSizeSwapped; static char* showlist = nullptr; // if true show a list instead of download tracks -static char* track = nullptr; // if not 0 only download this track, if 0 download all +static char* track = nullptr; // if not 0 only download this track, if 0 download all -static char* opt_dump_file = nullptr; // dump raw data to this file (optional) +static char* opt_dump_file = nullptr; // dump raw data to this file (optional) static char* opt_input_dump_file = nullptr; // if true input is from a dump-file instead of serial console static gbfile* dumpfile = nullptr; // used for creating bin/RAW datadump files, useful for testing static gbfile* in_file = nullptr; // used for reading from bin/RAW datadump files, useful for testing @@ -423,16 +423,6 @@ rd_init(const QString& fname) globalsat_probe_device(); } -static void -wr_init(const QString& fname) -{ - if (global_opts.debug_level > 1) { - printf(MYNAME " wr_init()\n"); - } - serial_init(qPrintable(fname)); -} - - static void rd_deinit() { @@ -455,18 +445,8 @@ rd_deinit() } } -static void -wr_deinit() -{ - if (global_opts.debug_level > 1) { - printf(MYNAME " wr_deinit()\n"); - } - serial_deinit(); -} - static void track_read(); - static void waypoint_read() { @@ -830,39 +810,22 @@ data_read() // This used the serial communication to the watch ff_vecs_t globalsat_sport_vecs = { - ff_type_serial, //type - FF_CAP_RW_ALL, //cap[3] - rd_init, //rd_init - wr_init, //wr_init - rd_deinit, //rd_deinit - wr_deinit, //wr_deinit - data_read, //read - nullptr, //write - nullptr, //exit - globalsat_args, //args - CET_CHARSET_ASCII, 0 //encode,fixed_encode - //NULL //name dynamic/internal? - , NULL_POS_OPS, - nullptr -}; - -// This reads from a RAW dump bile from a watch -// Useful for testing generated dumpfile with -// gpsbabel -i globalsat,dump-file= -f /dev/ttyUSB0 -o gpx,garminextensions -F <1:st gpx file name> -// gpsbabel -i globalsat-bin -f -o gpx,garminextensions -F <2:nd gpx file name> -ff_vecs_t globalsat_sport_fvecs = { - ff_type_serial, //type - FF_CAP_RW_ALL, //cap[3] - rd_init, //rd_init - wr_init, //wr_init - rd_deinit, //rd_deinit - wr_deinit, //wr_deinit - data_read, //read - nullptr, //write - nullptr, //exit - globalsat_args, //args - CET_CHARSET_ASCII, 0 //encode,fixed_encode - //NULL //name dynamic/internal? - , NULL_POS_OPS, + ff_type_serial, // type + { // cap + ff_cap_none, // waypoints + ff_cap_read, // tracks + ff_cap_none, // routes + }, + rd_init, // rd_init + nullptr, // wr_init + rd_deinit, // rd_deinit + nullptr, // wr_deinit + data_read, // read + nullptr, // write + nullptr, // exit + globalsat_args, // args + CET_CHARSET_ASCII, // encode + 0, // fixed_encode + NULL_POS_OPS, // position_ops nullptr }; diff --git a/itracku.cc b/itracku.cc index 9f3258e1c..01fa71772 100644 --- a/itracku.cc +++ b/itracku.cc @@ -29,11 +29,26 @@ ./gpsbabel -i itracku -f com14 -o gpx -F out.gpx */ +#include // for lround, round, floor +#include // for va_end, va_list, va_start +#include // for fprintf, stderr, SEEK_END, fflush, sscanf, vfprintf +#include +#include // for memcpy, strcmp, strlen, strncmp +#include // for gmtime + +#include // for QByteArray +#include // for QDate +#include // for QDateTime +#include // for QString +#include // for QTime +#include // for UTC +#include // for qPrintable + #include "defs.h" -#include "gbser.h" -#include -#include -#include +#include "gbser.h" // for gbser_read_line, gbser_write, gbser_deinit, gbser_flush, gbser_init, gbser_is_serial, gbser_read_wait, gbser_ERROR, gbser_OK +#include "gbfile.h" // for gbfile, gbfclose, gbfopen, gbfseek, gbfread, gbfwrite, gbftell, gbsize_t +#include "src/core/datetime.h" // for DateTime + #define MYNAME "itracku" @@ -243,7 +258,7 @@ deg_to_deg_min(double x) return (uint32_t)d * 1000000 + // multiply integer degrees to shift it to the right digits. - (uint32_t)(f * 600000.0) + // multiply fractional part to convert to minutes and to to shift it to the right digits. + (uint32_t)round((f * 600000.0)) + // multiply fractional part to convert to minutes and to to shift it to the right digits. ((sign > 0) ? 0 : 0x80000000); // add 0x80000000 for negative degrees } @@ -304,7 +319,7 @@ to_itracku_data_record(const Waypoint* wp, itracku_data_record* d) le_write32(d->longitude, deg_to_deg_min(wp->longitude)); le_write32(d->latitude, deg_to_deg_min(wp->latitude)); le_write32(d->creation_time, encode_itracku_time(wp->creation_time.toTime_t())); - d->speed = MPS_TO_KNOTS(wp->speed); + d->speed = round(MPS_TO_KNOTS(wp->speed)); le_write16(d->altitude, wp->altitude); d->flag = 0xff; } @@ -751,11 +766,9 @@ itracku_rt_deinit() /**************************************************************************/ -// capabilities below means: we can only read and write waypoints -// please change this depending on your new module ff_vecs_t itracku_vecs = { - ff_type_file, + ff_type_serial, { ff_cap_read /* waypoints */, ff_cap_read /* tracks */, @@ -766,7 +779,7 @@ ff_vecs_t itracku_vecs = { itracku_rd_deinit, nullptr, itracku_read, - itracku_write, + nullptr, itracku_exit, itracku_args, CET_CHARSET_ASCII, 0, /* ascii is the expected character set */ diff --git a/main.cc b/main.cc index 6c7c6a2fe..f87a31fbd 100644 --- a/main.cc +++ b/main.cc @@ -448,8 +448,14 @@ run(const char* prog_name) warning(MYNAME ": QTextCodec::codecForLocale() is %s, mib %d\n", defaultcodec->name().constData(),defaultcodec->mibEnum()); } - break; + + /* + * Undocumented '-@' option for test. + */ + case '@': + return validate_formats(); + /* * Undocumented '-vs' option for GUI wrappers. */ diff --git a/navicache.cc b/navicache.cc index d333480ee..835e4e9cf 100644 --- a/navicache.cc +++ b/navicache.cc @@ -204,31 +204,15 @@ nav_rd_deinit() { } -static void -nav_wr_init(const QString&) -{ - fatal(MYNAME ": Does not support writing Navicache files.\n"); -} - -static void -nav_wr_deinit() -{ -} - -static void -nav_write() -{ -} - ff_vecs_t navicache_vecs = { ff_type_file, { ff_cap_read, ff_cap_none, ff_cap_none }, nav_rd_init, - nav_wr_init, + nullptr, nav_rd_deinit, - nav_wr_deinit, + nullptr, nav_read, - nav_write, + nullptr, nullptr, nav_args, CET_CHARSET_UTF8, 0 /* CET-REVIEW */ diff --git a/pocketfms_fp.cc b/pocketfms_fp.cc index 0f959acdf..10bb7baed 100644 --- a/pocketfms_fp.cc +++ b/pocketfms_fp.cc @@ -82,12 +82,6 @@ rd_deinit() xml_deinit(); } -static void -wr_init(const QString&) -{ - fatal("Writing file of type %s is not supported\n", MYNAME); -} - void wpt_s(xg_string, const QXmlStreamAttributes*) { if (isFirst == 1) { @@ -187,7 +181,7 @@ ff_vecs_t pocketfms_fp_vecs = { ff_cap_read /* routes */ }, rd_init, - wr_init, + nullptr, rd_deinit, nullptr, data_read, diff --git a/saroute.cc b/saroute.cc index 1ca344f54..75cfe6cdd 100644 --- a/saroute.cc +++ b/saroute.cc @@ -447,17 +447,11 @@ my_read() } -static void -wr_init(const QString&) -{ - fatal(MYNAME ":Not enough information is known about this format to write it.\n"); -} - ff_vecs_t saroute_vecs = { ff_type_file, { ff_cap_none, ff_cap_read, ff_cap_none}, rd_init, - wr_init, + nullptr, rd_deinit, nullptr, my_read, diff --git a/testo.d/validate_formats.test b/testo.d/validate_formats.test new file mode 100644 index 000000000..4ff1c006b --- /dev/null +++ b/testo.d/validate_formats.test @@ -0,0 +1,2 @@ +gpsbabel -@ + diff --git a/tpo.cc b/tpo.cc index a90af11a4..dcb8a9756 100644 --- a/tpo.cc +++ b/tpo.cc @@ -92,9 +92,11 @@ #define MYNAME "TPO" static char* dumpheader = nullptr; +#ifdef ENABLE_TPO_WRITE static char* output_state = nullptr; +#endif -/* +#ifdef ENABLE_TPO_WRITE static arglist_t tpo2_args[] = { { "dumpheader", &dumpheader, "Display the file header bytes", @@ -103,7 +105,7 @@ arglist_t tpo2_args[] = { "CA", ARGTYPE_STRING, ARG_NOMINMAX} , ARG_TERMINATOR }; -*/ +#else // // Note that we've disabled the write capabilities for the tpo2 // format at present. The "testo" tests were failing on some @@ -115,6 +117,7 @@ static arglist_t tpo2_args[] = { ARG_TERMINATOR }; +#endif static arglist_t tpo3_args[] = { @@ -123,8 +126,10 @@ arglist_t tpo3_args[] = { static gbfile* tpo_file_in; +static double track_length; + +#ifdef ENABLE_TPO_WRITE static gbfile* tpo_file_out; -//static short_handle mkshort_handle; static double output_track_lon_scale; static double output_track_lat_scale; @@ -132,10 +137,10 @@ static double output_track_lat_scale; static unsigned int track_out_count; static double first_track_waypoint_lat; static double first_track_waypoint_lon; -static double track_length; static double last_waypoint_x; static double last_waypoint_y; static double last_waypoint_z; +#endif /*******************************************************************************/ /* READ */ @@ -1337,7 +1342,7 @@ tpo_read() - +#ifdef ENABLE_TPO_WRITE /*******************************************************************************/ /* WRITE */ /*******************************************************************************/ @@ -1374,8 +1379,6 @@ tpo_read() static void tpo_write_file_header() { - // this assertion will quiet gcc 7.3 warnings about output_state in the strncmp calls - // warning: argument 2 null where non-null expected [-Wnonnull] assert(output_state != nullptr); /* force upper-case state name */ @@ -1802,18 +1805,34 @@ tpo_write() track_out_count = 0; track_disp_all(tpo_track_hdr, tpo_track_tlr, tpo_track_disp); } +#endif // ENABLE_TPO_WRITE /* TPO 2.x format can read tracks only */ ff_vecs_t tpo2_vecs = { ff_type_file, /* ff_type_internal */ - /* { ff_cap_none | ff_cap_none, ff_cap_read | ff_cap_write, ff_cap_none | ff_cap_none }, */ +#ifdef ENABLE_TPO_WRITE + { ff_cap_none, (ff_cap)(ff_cap_read | ff_cap_write), ff_cap_none }, +#else { ff_cap_none, ff_cap_read, ff_cap_none }, +#endif tpo_rd_init, +#ifdef ENABLE_TPO_WRITE tpo_wr_init, +#else + nullptr, +#endif tpo_rd_deinit, +#ifdef ENABLE_TPO_WRITE tpo_wr_deinit, +#else + nullptr, +#endif tpo_read, +#ifdef ENABLE_TPO_WRITE tpo_write, +#else + nullptr, +#endif nullptr, tpo2_args, CET_CHARSET_ASCII, 0 /* CET-REVIEW */ @@ -1826,11 +1845,11 @@ ff_vecs_t tpo3_vecs = { ff_type_file, /* ff_type_internal */ { ff_cap_read, ff_cap_read, ff_cap_read }, tpo_rd_init, - tpo_wr_init, + nullptr, tpo_rd_deinit, - tpo_wr_deinit, + nullptr, tpo_read, - tpo_write, + nullptr, nullptr, tpo3_args, CET_CHARSET_ASCII, 0 /* CET-REVIEW */ diff --git a/vecs.cc b/vecs.cc index 6ec8a8816..2d5d0889f 100644 --- a/vecs.cc +++ b/vecs.cc @@ -1700,3 +1700,91 @@ disp_formats(int version) ; } } + +static bool +validate_vec(const vecs_t* vec) +{ + bool ok = true; + + if (!((vec->vec->cap[0]|vec->vec->cap[1]|vec->vec->cap[2]) & ff_cap_write)) { + if (vec->vec->wr_init != nullptr) { + printf("ERROR no write capability but non-null wr_init %s\n", vec->name); + ok = false; + } + } + if (!((vec->vec->cap[0]|vec->vec->cap[1]|vec->vec->cap[2]) & ff_cap_read)) { + if (vec->vec->rd_init != nullptr) { + printf("ERROR no read capbility but non-null rd_init %s\n", vec->name); + ok = false; + } + } + if ((vec->vec->cap[0]|vec->vec->cap[1]|vec->vec->cap[2]) & ff_cap_write) { + if (vec->vec->wr_init == nullptr) { + printf("ERROR write capability but null wr_init %s\n", vec->name); + ok = false; + } + } + if ((vec->vec->cap[0]|vec->vec->cap[1]|vec->vec->cap[2]) & ff_cap_read) { + if (vec->vec->rd_init == nullptr) { + printf("ERROR read capability but null rd_init %s\n", vec->name); + ok = false; + } + } + + if (vec->vec->wr_init != nullptr) { + if (vec->vec->write == nullptr) { + printf("ERROR nonnull wr_init but null write %s\n", vec->name); + ok = false; + } + if (vec->vec->wr_deinit == nullptr) { + printf("ERROR nonnull wr_init but null wr_deinit %s\n", vec->name); + ok = false; + } + } + if (vec->vec->wr_init == nullptr) { + if (vec->vec->write != nullptr) { + printf("ERROR null wr_init with non-null write %s\n", vec->name); + ok = false; + } + if (vec->vec->wr_deinit != nullptr) { + printf("ERROR null wr_init with non-null wr_deinit %s\n", vec->name); + ok = false; + } + } + + if (vec->vec->rd_init != nullptr) { + if (vec->vec->read == nullptr) { + printf("ERROR nonnull rd_init but null read %s\n", vec->name); + ok = false; + } + if (vec->vec->rd_deinit == nullptr) { + printf("ERROR nonnull rd_init but null rd_deinit %s\n", vec->name); + ok = false; + } + } + if (vec->vec->rd_init == nullptr) { + if (vec->vec->read != nullptr) { + printf("ERROR null rd_init with non-null read %s\n", vec->name); + ok = false; + } + if (vec->vec->rd_deinit != nullptr) { + printf("ERROR null rd_init with non-null rd_deinit %s\n", vec->name); + ok = false; + } + } + + return ok; +} + +int validate_formats() +{ + bool ok = true; + + const vecs_t* vec = vec_list; + while (vec->vec) { + ok = validate_vec(vec) && ok; + vec++; + } + + return ok? 0 : 1; +} diff --git a/vpl.cc b/vpl.cc index 8fe053f2d..5a575745c 100644 --- a/vpl.cc +++ b/vpl.cc @@ -155,12 +155,6 @@ vpl_read() } } -static void -vpl_wr_init(const QString&) -{ - fatal("Writing file of type %s is not support\n", MYNAME); -} - /******************************************************************************* * Local Functions *******************************************************************************/ @@ -222,7 +216,7 @@ ff_vecs_t vpl_vecs = { ff_cap_none /* routes */ }, vpl_rd_init, - vpl_wr_init, + nullptr, vpl_rd_deinit, nullptr, vpl_read, diff --git a/yahoo.cc b/yahoo.cc index cd2572a43..3e9bbf350 100644 --- a/yahoo.cc +++ b/yahoo.cc @@ -72,12 +72,6 @@ yahoo_rd_deinit() xml_deinit(); } -static void -yahoo_wr_init(const QString&) -{ - fatal("Writing file of type %s is not supported\n", MYNAME); -} - void wpt_s(xg_string, const QXmlStreamAttributes*) { wpt_tmp = new Waypoint; @@ -109,9 +103,9 @@ void wpt_addr(xg_string args, const QXmlStreamAttributes*) ff_vecs_t yahoo_vecs = { ff_type_file, - { ff_cap_read }, + { ff_cap_read, ff_cap_none, ff_cap_none }, yahoo_rd_init, - yahoo_wr_init, + nullptr, yahoo_rd_deinit, nullptr, yahoo_read, -- 2.30.2